package com.mai4j.maiadmin.controller.api;

import com.mai4j.maiadmin.configure.MaiProperties;
import com.mai4j.maiadmin.misc.StructMapper;
import com.mai4j.maiadmin.model.RespCode;
import com.mai4j.maiadmin.model.UserPrincipal;
import com.mai4j.maiadmin.model.dto.UserInfoDTO;
import com.mai4j.maiadmin.model.http.SignInReq;
import com.mai4j.maiadmin.model.http.response.SignInResp;
import com.mai4j.maiadmin.model.http.response.SignOutResp;
import com.mai4j.maiadmin.service.AuthenticationService;
import com.mai4j.maiadmin.support.I18nProvider;
import com.mai4j.maiadmin.support.cache.Session;
import com.mai4j.maiadmin.support.security.JwtUtils;
import com.mai4j.maiadmin.support.security.SecurityUtils;
import com.mai4j.maiadmin.support.web.utils.CookieUtil;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 微信公众号请关注: 开源螺丝钉
 * <br>
 * 码云请关注: <a href="https://gitee.com/xiyoufang">https://gitee.com/xiyoufang</a>
 * <br>
 * 哔哩哔哩请关注: <a href="https://space.bilibili.com/438927834">https://space.bilibili.com/438927834</a>
 *
 * @author xiyoufang
 */
@RestController
@RequestMapping("/api/authentication")
public class ApiAuthenticationController {

    private final AuthenticationService authenticationService;
    private final MaiProperties maiProperties;

    public ApiAuthenticationController(AuthenticationService authenticationService, MaiProperties maiProperties) {
        this.authenticationService = authenticationService;
        this.maiProperties = maiProperties;
    }

    @PostMapping("/sign-in")
    public ResponseEntity<SignInResp> signIn(@RequestBody @Validated SignInReq signInReq) {
        UserInfoDTO userInfoDTO = authenticationService.signIn(StructMapper.INSTANCE.signInReqToSignInDTO(signInReq));
        UserPrincipal userPrincipal = StructMapper.INSTANCE.userInfoDTOToUserPrincipal(userInfoDTO);
        String jwt = JwtUtils.create(maiProperties.getJwtKey(), userPrincipal, null);
        SecurityUtils.login(jwt, userPrincipal, userInfoDTO.getAuthorities()); // 进入登录状态
        CookieUtil.addCookie("jwt", jwt);
        return ResponseEntity.ok(new SignInResp()
                .setType(SignInResp.Type.Bearer)
                .setJwt(jwt)
                .setCode(RespCode.OK.getCode())
                .setMessage(I18nProvider.get("text.sign-in.successfully")));
    }

    /**
     * 注销
     *
     * @param authorization authorization
     * @return SignOutResp
     */
    @PreAuthorize("isAuthenticated()")
    @PostMapping("/sign-out")
    public ResponseEntity<SignOutResp> signOut(@RequestHeader("Authorization") String authorization) {
        String[] parsed = authorization.split(" ");
        if (parsed.length == 2
                && "Bearer".equalsIgnoreCase(parsed[0])
                && JwtUtils.verify(maiProperties.getJwtKey(), parsed[1])
                && Session.isValid(parsed[1])) { // 授权头jwt有效
            SecurityUtils.logout();
        }
        return ResponseEntity.ok(new SignOutResp()
                .setCode(RespCode.OK.getCode())
                .setMessage(I18nProvider.get("text.sign-out.successfully")));
    }
}
